/**
 * @Description: 系统用户
 * @author dazer
 * @date 2019/2/1 下午12:09
 */
import React, { Fragment } from 'react';
import Modal from 'drag-modal';
import {
  AutoComplete,
  BackTop,
  Button,
  Card,
  Checkbox,
  Col,
  Divider,
  Form,
  Icon,
  Input,
  Radio,
  Row,
  Select,
  Spin,
  Tag,
  Tooltip,
  Upload,
} from 'antd';
import { formatMessage, FormattedMessage } from 'umi/locale';
import 'antd/dist/antd.css';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import { requestLists, requestPromise } from '@/utils/request';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import BaseForm from '@/components/ourslook/BaseForm';
import ETable from '@/components/ourslook/ETable';
import { getWebPath } from '../../utils/request';
import uiUtils, { hasPermission, rulesReg, rulesRemote } from '../../utils/uiUtils';
import styles from '../../utils/ourslook.less';

const FormItem = Form.Item;
const Option = Select.Option;
const RadioGroup = Radio.Group;
const TextArea = Input.TextArea;
const Password = Input.Password;
const CheckboxGroup = Checkbox.Group;

const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

// @coming({ title: '精彩即将呈现！', value: Date.now() + 1000 * 60 * 60 * 24 * 2 })
@connect(() => ({}))
class Sysuser extends React.Component {
  params = {
    page: 1,
    limit: 10,
  };

  formItemLayout = {
    labelCol: { span: 5 },
    wrapperCol: { span: 19 },
  };

  /**
   * https://ant-design.gitee.io/components/table-cn/
   *
   * 需要指定 column 的 width 属性，否则列头和内容可能不对齐。（必须留一列不设宽度或者minWidth以适应弹性布局）
   * 建议指定 scroll.x 为大于表格宽度的固定值或百分比。注意，且非固定列宽度之和不要超过 scroll.x, 一般无table正常展开的宽度
   * 未知长度字段或者字符特别多的字段不要放置在列表
   */
  columns = [
    {
      title: '',
      width: 30,
      align: 'center',
      fixed: 'left',
      render: (value, record, index) => `${index + 1}`,
    },
    {
      title: '用户ID',
      dataIndex: 'userId',
      width: 80,
      align: 'left',
      fixed: 'left',
      sorter: false,
    },
    { title: '用户名', dataIndex: 'username', width: 100 },
    { title: '手机号', dataIndex: 'mobile', width: 200 },
    {
      title: '邮箱',
      dataIndex: 'email',
      render: (value, row, index) => {
        if (value !== undefined && row.nickName !== undefined) {
          return `${row.nickName}<${value}>`;
        }
        return value;
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 60,
      align: 'center',
      render: (value, record, index) =>
        value === 0 ? (
          <Tag style={{ cursor: 'default' }} className={styles.label_danger}>
            禁用
          </Tag>
        ) : (
          <Tag style={{ cursor: 'default' }} className={styles.label_success}>
            正常
          </Tag>
        ),
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'create_time',
      width: 180,
      align: 'center',
      sorter: true,
    },
    {
      title: '操作',
      dataIndex: '',
      width: 120,
      align: 'center',
      fixed: 'right',
      render: (value, record, index) => (
        <React.Fragment>
          <a
            hidden={!hasPermission('sys:user:info')}
            onClick={() => {
              this.setStateByTableColume(record, index);
              this.view();
            }}
          >
            <Tooltip title={<FormattedMessage id="ours.curd.list.info" defaultMessage="查看" />}>
              <Icon type="info" />
            </Tooltip>
          </a>
          <Divider
            hidden={!(hasPermission('sys:user:save') && hasPermission('sys:user:update'))}
            type="vertical"
          />
          <a
            hidden={!hasPermission('sys:menu:update')}
            onClick={() => {
              this.setStateByTableColume(record, index);
              this.update();
            }}
          >
            <Tooltip title={<FormattedMessage id="ours.curd.list.update" defaultMessage="修改" />}>
              <Icon type="edit" />
            </Tooltip>
          </a>
          <Divider
            hidden={!(hasPermission('sys:user:save') && hasPermission('sys:user:update'))}
            type="vertical"
          />
          <a
            hidden={!hasPermission('sys:menu:update')}
            onClick={() => {
              this.setStateByTableColume(record, index);
              this.showResetPassword();
            }}
          >
            <Tooltip
              title={
                <FormattedMessage id="ours.curd.list.resetPasswod" defaultMessage="重置密码" />
              }
            >
              <Icon type="rollback" />
            </Tooltip>
          </a>
        </React.Fragment>
      ),
    },
  ];

  constructor(props) {
    super(props);
    this.state = {
      showList: 1, //1:显示列表、2:显示新增
      formList: Sysuser.getFormList(),
      selectedRows: [],
      selectedIds: [],
      selectedIndexs: [],
      editModalTitle: null,
      editModalType: null,
      editModel: null,
      editModelConfirmLoading: false,
      schoolList: [],
      roleList: [],
    };
  }

  static getFormList = () => [
    {
      type: 'INPUT',
      field: 'username',
      label: '用户名',
      placeholder: '用户名',
    },
    {
      type: 'SELECT',
      field: 'roleId',
      placeholder: '用户角色',
      initialValue: '',
      list: [{ id: '', name: '请选择用户角色' }],
      showSearch: true,
    },
    {
      type: 'INPUT',
      field: 'mobile',
      label: '手机号',
      placeholder: '手机号',
    },
    {
      type: 'INPUT',
      field: 'email',
      label: '邮箱',
      placeholder: '邮箱',
    },
    {
      type: 'SELECT',
      field: 'status',
      label: '状态',
      placeholder: '状态',
      list: [{ id: '', name: '请选择状态' }, { id: '1', name: '正常' }, { id: '0', name: '禁用' }],
    },
  ];

  componentDidMount() {
    this.requestList();
    this.getRoleList();
    this.getIsSuperAdmin();
  }

  componentWillUnmount() {}

  /**
   * 根据 formItem field 取值 查找formItem
   * @param formItemField obj的field字段
   * @returns 一个对象
   */
  findFormListItemByField = formItemField =>
    this.state.formList.find((value, index, array) => value.field === formItemField);

  query = fieldParams => {
    this.params = JSON.parse(JSON.stringify(Object.assign(this.params, fieldParams)));
    this.requestList();
  };

  add = () => {
    this.setState({
      editModalType: 'add',
      editModalTitle: formatMessage({ id: 'ours.curd.list.create' }), //创建
      editModel: { status: 1, roleIdList: [] },
      showList: 2,
    });
  };

  update = () => {
    const { selectedRows, selectedIds, selectedIndexs } = this.state;
    if (!selectedRows) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-please' }));
      return;
    }
    if (selectedRows.length > 1) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-one-please' }));
      return;
    }
    this.setState({
      editModalType: 'update',
      editModalTitle: <FormattedMessage id="ours.curd.list.edit" defaultMessage="编辑" />,
      editModel: JSON.parse(JSON.stringify(selectedRows[0])),
      showList: 2,
    });
    this.getInfo(selectedRows[0].userId);
  };

  showResetPassword = () => {
    const { selectedRows, selectedIds, selectedIndexs } = this.state;
    if (!selectedRows) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-please' }));
      return;
    }
    if (selectedRows.length > 1) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-one-please' }));
      return;
    }
    this.setState({
      resetPsswordVisible: true,
      editModel: JSON.parse(JSON.stringify(selectedRows[0])),
    });
  };

  view = () => {
    const { selectedRows, selectedIds, selectedIndexs } = this.state;
    if (!selectedRows) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-please' }));
      return;
    }
    if (selectedRows.length > 1) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-one-please' }));
      return;
    }
    this.setState({
      editModalType: 'view',
      editModalTitle: <FormattedMessage id="ours.curd.list.info" defaultMessage="查看" />,
      editModel: selectedRows[0],
      showList: 2,
    });
    this.getInfo(selectedRows[0].userId);
  };

  del = () => {
    const selectedRows = this.state.selectedRows;
    const userIds = [];
    for (let i = 0; i < selectedRows.length; i += 1) {
      userIds.push(selectedRows[i].userId);
    }

    uiUtils.showConfirm(formatMessage({ id: 'ours.curd.show-alert.confirm-delete' }), () => {
      this.setState({
        loading: true,
      });
      requestPromise(`${getWebPath('/sys/user/delete')}`, {
        method: 'POST',

        body: userIds,
      }).then(res => {
        this.setState({
          loading: false,
        });
        if (res && res.code === 0) {
          uiUtils.showMessage(
            formatMessage({ id: 'ours.curd.show-alert.operate-success' }),
            'success'
          );
          this.requestList();
        }
      });
    });
  };

  saveOrUpdate = () => {
    const editModalType = this.state.editModalType;
    //不能双向绑定，这里只能原对象、新对象进行合并.
    const user = Object.assign(this.state.editModel, this.editForm.props.form.getFieldsValue());
    console.log(this);
    this.editForm.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        // submit the values
        const url = user.userId == null ? '/sys/user/save' : '/sys/user/update';

        this.setState({
          editModelConfirmLoading: true,
        });
        requestPromise(`${getWebPath(url)}`, {
          method: 'POST',
          body: user,
        }).then(res => {
          this.setState({
            editModelConfirmLoading: false,
          });

          if (res && res.code === 0) {
            uiUtils.showMessage(
              formatMessage({ id: 'ours.curd.show-alert.operate-success' }),
              'success'
            );
            this.setState({
              showList: 1,
            });

            //新增重新置为第一页
            if (!user.userId) {
              this.params.page = 1;
            }
            this.requestList();
          }
        });
      }
    });
  };

  getRoleList = () => {
    requestPromise(`${getWebPath('/sys/role/select')}`, {
      method: 'GET',
    }).then(res => {
      if (res && res.code === 0) {
        const roles = res.list || [];
        const newRoles = [
          { id: '', name: '请选择用户角色' },
          ...roles.map(e => ({ id: e.roleId, name: e.roleName })),
        ];

        const { formList: formListNew } = this.state;
        const formItem = this.findFormListItemByField('roleId');
        formItem.list = newRoles;
        this.setState({
          formList: formListNew,
          roleList: roles,
        });
      }
    });
  };

  getIsSuperAdmin = () => {
    requestPromise(`${getWebPath('/sys/user/isSuperAdmin')}`, {
      method: 'GET',
    }).then(res => {
      if (res && res.code === 0) {
        this.setState({
          schoolList: res.data.schoolList,
        });
      }
    });
  };

  getInfo = userId => {
    this.setState({
      editModelConfirmLoading: true,
    });
    requestPromise(getWebPath(`/sys/user/infoVo/${userId}`), {
      method: 'GET',
    }).then(res => {
      if (res && res.code === 0) {
        this.setState({
          editModel: res.user,
        });
      }
      this.setState({
        editModelConfirmLoading: false,
      });
    });
  };

  setStateByTableColume = (record, index) => {
    this.state = {
      ...this.state,
      selectedRows: [record],
      selectedIds: [record.id],
      selectedIndexs: [index],
    };
  };

  /**
   * 表格 筛选和排序 回调
   */
  filtersSorterChange = tableParams => {
    this.params = JSON.parse(JSON.stringify(Object.assign(this.params, tableParams)));
    this.requestList();
  };

  requestList = () => {
    requestLists(this, `${getWebPath('/sys/user/list')}`, this.params);
  };

  vShow = showListNum => ({ display: this.state.showList === showListNum ? 'block' : 'none' });

  exportsInfoToExcel = isExcel => {
    const data = `isCvs=${isExcel ? 'false' : 'true'}`;
    window.location.href = `${getWebPath()}sys/user/exportsSysUserToExcel?${data}`;
  };

  render() {
    const style = {
      style: {
        marginLeft: 10,
        marginTop: 10,
      },
      disabled: this.state.selectedIndexs.length <= 0,
    };
    const importStyle = {
      style: {
        marginLeft: 10,
        marginTop: 10,
      },
    };

    /* eslint-disable react/jsx-no-bind */
    return (
      <PageHeaderWrapper title="">
        <Card
          bordered={false}
          style={{ ...this.vShow(1) }}
          className={styles.oursCard}
          bodyStyle={{ padding: '20px' }}
        >
          <BaseForm
            formList={this.state.formList}
            loading={this.state.loading}
            filterSubmit={this.query}
          />

          <Button
            type="primary"
            icon="plus"
            onClick={this.add}
            hidden={!hasPermission('sys:user:save')}
          >
            <FormattedMessage id="ours.curd.list.add" defaultMessage="新增" />
          </Button>
          <Button
            type="primary"
            icon="upload"
            {...importStyle}
            onClick={() => {
              this.setState({
                importInfoVisible: true,
              });
            }}
          >
            导入
          </Button>
          <Button
            type="primary"
            icon="delete"
            {...style}
            onClick={this.del}
            hidden={!hasPermission('sys:user:delete')}
          >
            <FormattedMessage id="ours.curd.list.delete" defaultMessage="删除" />
          </Button>

          <div className="content-wrap">
            <ETable
              onSelectRow={uiUtils.onSelectRow.bind(this)}
              primaryKey="userId"
              selectedIndexs={this.state.selectedIndexs}
              selectedRows={this.state.selectedRows}
              selectedIds={this.state.selectedIds}
              onChange={this.filtersSorterChange}
              columns={this.columns}
              dataSource={this.state.list}
              pagination={this.state.pagination}
              loading={this.state.loading}
              scroll={{ x: 1180 }}
            />
          </div>
        </Card>

        <BackTop />

        <Spin spinning={this.state.editModelConfirmLoading} delay={10}>
          {//返回null,这里对不用的组件进行销毁
          this.state.showList === 1 ? null : (
            <Card
              title={this.state.editModalTitle}
              bordered={false}
              actions={[
                <div>
                  <React.Fragment>
                    <Button
                      type="primary"
                      hidden={this.state.editModalType === 'view'}
                      style={{ marginRight: '18px' }}
                      onClick={this.saveOrUpdate}
                    >
                      <FormattedMessage id="ours.curd.add.save" defaultMessage="保存" />
                    </Button>
                    <Button
                      style={{ marginRight: '18px' }}
                      onClick={() => {
                        this.editForm.props.form.resetFields();
                        this.setState({ showList: 1 });
                      }}
                    >
                      <FormattedMessage id="ours.curd.add.back" defaultMessage="返回" />
                    </Button>
                  </React.Fragment>
                </div>,
              ]}
              style={{ ...this.vShow(2) }}
              bodyStyle={{ padding: '20px' }}
            >
              <EditForm
                type={this.state.editModalType}
                model={this.state.editModel}
                schoolList={this.state.schoolList}
                roleList={this.state.roleList}
                wrappedComponentRef={inst => {
                  this.editForm = inst;
                }}
              />
            </Card>
          )}
        </Spin>
        <ResetPsswordForm
          resetPasswodModel={this.state.editModel}
          onCancel={() => {
            this.setState({ resetPsswordVisible: false });
          }}
          visible={this.state.resetPsswordVisible}
          wrappedComponentRef={inst => {
            this.resetPsswordForm = inst;
          }}
        />
        <ImportInfoForm
          onCancel={() => {
            this.setState({ importInfoVisible: false });
            this.importInfoForm.setState({
              uploadResultDisplay: false,
              uploadResultInfo: '',
              fileList: [],
            });
          }}
          demoDown={() => {
            this.exportsInfoToExcel(true);
          }}
          refresList={() => {
            this.requestList();
          }}
          visible={this.state.importInfoVisible}
          wrappedComponentRef={inst => {
            this.importInfoForm = inst;
          }}
        />
      </PageHeaderWrapper>
    );
  }
}

export default Sysuser;

/**
 * 重置密码
 */
@Form.create()
class ResetPsswordForm extends React.Component {
  static propTypes = {
    visible: PropTypes.bool, //第modal是否显示
    onCancel: PropTypes.func, //modal关闭事件
    resetPasswodModel: PropTypes.object,
  };

  static defaultProps = {
    visible: false,
    onCancel: () => {},
    resetPasswodModel: null,
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  getRandomPassword = () => {
    this.setState({ reandomLoading: true });
    requestPromise(`${getWebPath('sys/user/changeRandomPwd')}`, {
      method: 'GET',
    }).then(res => {
      if (res.code === 0) {
        this.setState({ reandomLoading: false });
        this.props.form.setFieldsValue({ repeatPassword: res.pwd });
      }
    });
  };

  resetPassword = () => {
    const user = {
      password: this.props.form.getFieldValue('repeatPassword'),
      userId: this.props.resetPasswodModel.userId,
    };
    if (user.password === undefined || user.password === '') {
      uiUtils.showMessage(`新密码不能为空！`, 'error');
      return;
    }
    this.setState({ resetPasswordLoading: true });
    const url = '/sys/user/resetPassword';
    requestPromise(`${getWebPath(url)}`, {
      method: 'POST',
      body: user,
      contentType: 'application/x-www-form-urlencoded',
    }).then(res => {
      this.setState({ resetPasswordLoading: false });
      if (res && res.code === 0) {
        uiUtils.showMessage(res.msg, 'success');
        this.props.onCancel();
      }
    });
  };

  sendResetPasswordEmail = () => {
    // eslint-disable-next-line no-restricted-globals
    const resetPwdUrl = `${location.protocol}//${location.host}${
      location.pathname
    }#/user/reset-password`;
    const user = {
      userId: this.props.resetPasswodModel.userId,
      url: resetPwdUrl,
    };
    this.setState({ sendResetEmailLoading: true });
    const url = '/sys/user/sendResetPasswordEmail';
    requestPromise(`${getWebPath(url)}`, {
      method: 'POST',
      body: user,
      contentType: 'application/x-www-form-urlencoded',
    }).then(res => {
      this.setState({ sendResetEmailLoading: false });
      if (res && res.code === 0) {
        uiUtils.showMessage(res.msg, 'success');
        this.props.onCancel();
      }
    });
  };

  render() {
    const visible = this.props.visible;
    const onCancel = this.props.onCancel;
    const resetPasswodModel = this.props.resetPasswodModel || { email: '', repeatPassword: '' };
    const {
      form,
      form: { getFieldDecorator, getFieldValue, setFieldsValue },
    } = this.props;
    const title = `密码重置：${resetPasswodModel.username}`;

    //校验文档：https://ant.design/components/form-cn/#%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99
    return (
      <Modal
        title={title}
        visible={visible}
        onCancel={onCancel}
        destroyOnClose
        closable
        cancelText="取消"
        width={600}
        saveDistance={0}
        footer={null}
      >
        <Form layout="vertical">
          <FormItem label="发送密码重置邮件">
            <Row style={{ marginLeft: '40px' }}>
              向用户绑定的邮箱地址 {resetPasswodModel.email}{' '}
              发送密码重置邮件，然后用户可通过邮件中的密码重置链接自行设置新密码。
              <Row style={{ marginTop: '10px' }}>
                <Button
                  type="primary"
                  size="small"
                  loading={this.state.sendResetEmailLoading}
                  onClick={() => {
                    this.sendResetPasswordEmail();
                  }}
                >
                  <FormattedMessage id="ours.curd.list.sendEmail" defaultMessage="发送邮件" />
                </Button>
              </Row>
            </Row>
          </FormItem>
          <hr
            style={{
              marginTop: '20px',
              marginBottom: '20px',
              border: 0,
              borderTop: '1px solid #eee',
            }}
          />
          <FormItem label="手动重置">
            <Row style={{ marginLeft: '40px' }}>
              为用户设置新密码，并立即生效，需要通过其它方式来告知用户新密码。
              <Row style={{ marginTop: '10px' }}>
                {getFieldDecorator('repeatPassword', {
                  initialValue: resetPasswodModel.repeatPassword,
                })(
                  <Input.Password
                    type="text"
                    maxLength={50}
                    placeholder="设置用户的新密码"
                    style={{ width: '50%' }}
                  />
                )}
                <Button
                  type="primary"
                  size="small"
                  style={{ marginLeft: '10px' }}
                  loading={this.state.reandomLoading}
                  icon="setting"
                  onClick={() => {
                    this.getRandomPassword();
                  }}
                >
                  <FormattedMessage
                    id="ours.curd.list.randomPasswod"
                    defaultMessage="生成随机密码"
                  />
                </Button>
              </Row>
              <Row style={{ marginTop: '10px' }}>
                <Button
                  type="primary"
                  size="small"
                  loading={this.state.resetPasswordLoading}
                  icon="check"
                  onClick={() => {
                    this.resetPassword();
                  }}
                >
                  <FormattedMessage id="ours.curd.list.resetPasswod" defaultMessage="重置密码" />
                </Button>
              </Row>
            </Row>
          </FormItem>
        </Form>
      </Modal>
    );
  }
}

/**
 * 导入信息
 */
@Form.create()
class ImportInfoForm extends React.Component {
  static propTypes = {
    visible: PropTypes.bool, //第modal是否显示
    onCancel: PropTypes.func, //modal关闭事件
    demoDown: PropTypes.func,
    refresList: PropTypes.func, //刷新列表
  };

  static defaultProps = {
    visible: false,
    onCancel: () => {},
    demoDown: () => {},
    refresList: () => {},
  };

  constructor(props) {
    super(props);
    this.state = {
      demoloadingLoading: false, //下载按钮是否loading中
      uploadLoading: false, //导入loading框框
      uploadResultDisplay: false, //导入结果是否显示
      uploadResultInfo: '', //导入结果信息
      fileList: [],
    };
  }

  handleUploadOnRemove = file => {
    this.setState({
      fileList: [],
    });
  };

  handleUploadOnChange = info => {
    // 状态有：uploading done error removed
    if (info.file.status === 'done') {
      //这个Upload组件比较特殊，这里在OnChange方法手工设置value,不做延迟，就设置不了被覆盖了。
      this.setState({
        fileList: info.fileList,
      });
      const response = info.fileList[0].response;
      if (response) {
        this.setState({
          uploadLoading: false,
        });
        if (response.code === 0) {
          uiUtils.showMessage(`${info.file.name} 系统用户导入完毕,请下载结果excel`, 'success');
          this.setState({
            uploadResultDisplay: true,
            uploadResultInfo: response.result,
          });
          if (this.props.refresList) {
            this.props.refresList();
          }
        } else {
          this.setState({
            uploadResultDisplay: true,
            uploadResultInfo: response.msg,
          });
        }
      }
    } else if (info.file.status === 'error') {
      uiUtils.showMessage(`${info.file.name} 文件上传失败.`, 'error');
      this.setState({
        uploadLoading: false,
      });
    } else if (info.file.status === 'uploading') {
      this.setState({
        uploadLoading: true,
      });
    }
  };

  render() {
    const visible = this.props.visible;
    const onCancel = this.props.onCancel;
    const demoloadingLoading = this.state.demoloadingLoading;
    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">上传</div>
      </div>
    );
    const uploadProps = {
      action: `${getWebPath('/user/importSysUserFromExcel')}`,
      name: 'myfile',
      data: {},
      withCredentials: true,
      headers: {
        authorization: 'authorization-text',
      },
      onChange: this.handleUploadOnChange,
      onRemove: this.handleUploadOnRemove,
      multiple: false,
      accept:
        '.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,' +
        '',
    };
    const {
      form,
      form: { getFieldDecorator, getFieldValue, setFieldsValue },
    } = this.props;
    const formItemLayout = {
      labelCol: { span: 5 },
      wrapperCol: { span: 18 }, //5+19=24,少一个栅格
    };
    const colSpanLayout = { md: 24, sm: 24 }; //每一col跨?列
    const rowGutterPxLayout = { md: 24, sm: 24 }; //col之间的间隔?px

    //校验文档：https://ant.design/components/form-cn/#%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99
    return (
      <Modal
        title="导入信息"
        visible={visible}
        onCancel={onCancel}
        destroyOnClose
        closable
        okButtonProps={{ icon: 'down-circle', htmlType: 'submit', disabled: true, hidden: true }}
        cancelButtonProps={{ loading: this.state.uploadLoading }}
        okText="确定上传"
        width={600}
        saveDistance={0}
        footer={null}
      >
        <Form layout="horizontal">
          <Row gutter={{ ...rowGutterPxLayout }}>
            <Col {...colSpanLayout}>
              <FormItem
                label="样例下载"
                colon={false}
                {...{
                  labelCol: { span: 5 },
                  wrapperCol: { span: 10 }, //5+19=24,少一个栅格
                }}
              >
                <Button
                  size="small"
                  loading={demoloadingLoading}
                  icon="upload"
                  onClick={() => {
                    this.props.demoDown();
                    this.setState({
                      demoloadingLoading: true,
                    });
                    //这里延迟5s关闭loading
                    setTimeout(() => {
                      this.setState({
                        demoloadingLoading: false,
                      });
                    }, 1000 * 5);
                  }}
                >
                  样例下载
                </Button>
              </FormItem>
            </Col>
            <Col {...colSpanLayout}>
              <FormItem
                label="文件"
                extra={
                  <Fragment>
                    最大支持 10000 条记录（支持 xls、xlsx，文件大小请控制在 5MB 以内;
                    <span style={{ display: 'block', color: 'blue' }}>
                      1: 按照模板要求填写信息，相关数据不要写成E+22科学计数法，日期请使用文本格式；
                    </span>
                    <span style={{ display: 'block', color: 'blue' }}>
                      2: 点击红色部分下载【查看失败原因】，对症修改，成功率更高。；
                    </span>
                    <span style={{ display: 'block', color: 'blue' }}>
                      3: 简单一点，全选excel，设置所有单元格格式，纯文本；
                    </span>
                  </Fragment>
                }
                {...formItemLayout}
              >
                {getFieldDecorator('file', {
                  initialValue: '',
                  rules: [
                    {
                      required: true,
                      message: '文件必填',
                    },
                  ],
                })(
                  <Spin spinning={this.state.uploadLoading} delay={0}>
                    <Upload
                      listType="picture-card"
                      showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
                      {...uploadProps}
                    >
                      {this.state.fileList && this.state.fileList.length >= 1 ? null : uploadButton}
                    </Upload>
                  </Spin>
                )}
                <div
                  style={{
                    display: this.state.uploadResultDisplay ? 'block' : 'none',
                    lineHeight: '16px',
                    color: 'red',
                  }}
                >
                  <span dangerouslySetInnerHTML={{ __html: this.state.uploadResultInfo }} />
                </div>
              </FormItem>
            </Col>
          </Row>
        </Form>
      </Modal>
    );
  }
}

/**
 *  新增、编辑、复制、查看的Form
 */

/* eslint react/no-multi-comp:0 */
class EditForm extends React.Component {
  mailSuffix = ['163.com', '126.com', 'gmail.com', 'qq.com', 'hotmail.com', 'sohu.com', 'sina.com'];

  static propTypes = {
    type: PropTypes.string, //form类型，可选值：add（增加）、update（修改）、copy（复制）、view（查看）、
    model: PropTypes.object, //数据模型model，对应后台的model
    schoolList: PropTypes.object, //学校列表
    roleList: PropTypes.object, //角色列表
  };

  static defaultProps = {
    type: '', //表单布局数组
    model: null,
    schoolList: [],
    roleList: [],
  };

  constructor(props) {
    super(props);
    this.state = {
      mailDataSource: [],
    };
  }

  /**
   * 生命周期-属性发生变化...componentWillReceiveProps
   * 这里的nextProps，可以获取到所有的属性。
   * 目前没用，因为 dialog 每次都被销毁了
   */
  componentWillReceiveProps(nextProps) {}

  getPropsLatestByKey = prop => {
    const model = this.props.model || {};
    const finalModel = Object.assign(model, this.props.form.getFieldsValue());
    return finalModel[prop];
  };

  getPropsByKey = prop => {
    const model = this.props.model || {};
    return model[prop];
  };

  autoCompleteHandleSearch = value => {
    this.setState({
      mailDataSource:
        !value || value.indexOf('@') === -1
          ? []
          : this.mailSuffix
              .map(en => `${value.split('@', 2)[0]}@${en}`)
              .filter(en => en.indexOf(value.split('@', 2)[1]) !== -1),
    });
  };

  render() {
    const type = this.props.type; //编辑是：新增（add）、编辑(edit)、复制(copy)、还是查看(view)
    const model = this.props.model || { type: '' };
    const { getFieldDecorator } = this.props.form;
    const formItemLayout = {
      labelCol: { span: 5 },
      wrapperCol: { span: 18 }, //5+19=24,少一个栅格
    };
    const colSpanLayout = { md: 12, sm: 24 }; //每一col跨?列
    const rowGutterPxLayout = { md: 24, sm: 16 }; //col之间的间隔?px
    const inputCodeDisabled = {
      disabled: type === 'update',
    };
    //校验文档：https://ant.design/components/form-cn/#%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99
    const inputUsernameRules =
      type !== 'view'
        ? [
            {
              required: true,
              message: '用户名必填',
            },
            {
              whitespace: true,
              message: '不能包含空白符',
            },
            {
              min: 3,
              max: 50,
              message: '长度不在范围内',
            },
            rulesReg('username'),
            rulesRemote('POST', getWebPath('/sys/user/checkUsernameExist'), {
              usernameOldValue: this.getPropsByKey('username'),
              userinfoIsAdd: type === 'add',
            }),
          ]
        : [];
    const inputMobileRules =
      type !== 'view'
        ? [
            /*{
            required: true,
            message: '手机号必填',
          },
          {
            min: 11,
            max: 11,
            message: '手机号必须是11个字符',
          },
          rulesReg('mobile'),*/
            rulesRemote('POST', getWebPath('/sys/user/checkMobileExist'), {
              mobileOldValue: this.getPropsByKey('mobile'),
              userinfoIsAdd: type === 'add',
            }),
          ]
        : [];
    return (
      <Form layout="horizontal">
        <Row gutter={{ ...rowGutterPxLayout }}>
          <Col {...colSpanLayout}>
            <FormItem label="用户名" {...formItemLayout}>
              {type === 'view'
                ? model.username
                : getFieldDecorator('username', {
                    initialValue: model.username,
                    rules: inputUsernameRules,
                  })(<Input type="text" maxLength={50} placeholder="用户名" />)}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="密码" {...formItemLayout}>
              {type === 'view'
                ? '******'
                : getFieldDecorator('password', {
                    initialValue: model.password,
                    rules: [
                      {
                        min: 6,
                        message: '密码最少6位',
                      },
                    ],
                  })(<Input type="text" maxLength={200} autocomplete="off" placeholder="密码" />)}
            </FormItem>
          </Col>
        </Row>
        <Row gutter={{ ...rowGutterPxLayout }}>
          <Col {...colSpanLayout}>
            <FormItem label="邮箱" {...formItemLayout}>
              {type === 'view'
                ? model.email
                : getFieldDecorator('email', {
                    initialValue: model.email,
                    rules: [
                      {
                        min: 5,
                        max: 50,
                        message: '长度不在范围内',
                      },
                      rulesReg('email'),
                      rulesRemote('POST', getWebPath('/sys/user/checkEamilExist'), {
                        emailOldValue: this.getPropsByKey('email'),
                        userinfoIsAdd: false,
                      }),
                    ],
                  })(
                    <AutoComplete
                      placeholder="邮箱"
                      style={{ width: '94%' }}
                      dataSource={this.state.mailDataSource}
                      onSearch={this.autoCompleteHandleSearch}
                    />
                  )}
              &nbsp;&nbsp;
              <Tooltip placement="right" title="用于重置密码">
                <Icon type="question-circle" />
              </Tooltip>
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="手机号" {...formItemLayout}>
              {type === 'view'
                ? model.mobile
                : getFieldDecorator('mobile', {
                    initialValue: model.mobile,
                    rules: inputMobileRules,
                  })(
                    <Input
                      type="text"
                      {...inputCodeDisabled}
                      maxLength={11}
                      autocomplete="off"
                      placeholder="手机号"
                    />
                  )}
            </FormItem>
          </Col>
        </Row>
        <Row gutter={{ ...rowGutterPxLayout }}>
          {/*<Col {...colSpanLayout}>*/}
          {/*<FormItem label="学校" {...formItemLayout}>*/}
          {/*{type === 'view'*/}
          {/*? model.schoolName*/}
          {/*: getFieldDecorator('extends1', {*/}
          {/*initialValue: model.extends1 || '',*/}
          {/*})(*/}
          {/*<Select*/}
          {/*style={{width: '100%'}}*/}
          {/*{...inputCodeDisabled}*/}
          {/*placeholder="请选择学校"*/}
          {/*>*/}
          {/*<option value="">请选择学校</option>*/}
          {/*{uiUtils.getOptionList(this.props.schoolList)}*/}
          {/*</Select>*/}
          {/*)}*/}
          {/*</FormItem>*/}
          {/*</Col>*/}
          <Col {...colSpanLayout}>
            <FormItem label="状态" {...formItemLayout}>
              {type === 'view'
                ? model.status === 1
                  ? '正常'
                  : '禁用'
                : getFieldDecorator('status', {
                    initialValue: model.status,
                  })(
                    <RadioGroup>
                      <Radio value={0}>禁用</Radio>
                      <Radio value={1}>正常</Radio>
                    </RadioGroup>
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="真实姓名" {...formItemLayout}>
              {type === 'view'
                ? model.nickName
                : getFieldDecorator('nickName', {
                    initialValue: model.nickName,
                  })(<Input type="text" maxLength={50} placeholder="真实姓名" />)}
            </FormItem>
          </Col>
        </Row>
        <Row gutter={{ ...rowGutterPxLayout }}>
          <Col {...colSpanLayout}>
            <FormItem label="角色" {...formItemLayout}>
              {type === 'view'
                ? model.roleNames
                : getFieldDecorator('roleIdList', {
                    initialValue: model.roleIdList,
                  })(
                    <CheckboxGroup
                      options={[
                        ...this.props.roleList.map(e => ({ label: e.roleName, value: e.roleId })),
                      ]}
                      onChange={checkedValues => {}}
                    />
                  )}
            </FormItem>
          </Col>
        </Row>
      </Form>
    );
  }
}

/* eslint-disable no-class-assign */
//无更多的绑定， 请用 @Form.create() 注解替换
EditForm = Form.create({})(EditForm);
